/// @file circularbuffer.cpp
/// @brief Implementation of the CircularBuffer class
/// @date 23/09/2009
/// @author J.Stadelmann, Reds, Heig-vd

#include "circularbuffer.h"
#include <iostream>

using namespace std;

//*************************************************************************************************
// Constructor
//*************************************************************************************************
CircularBuffer::CircularBuffer()
{
    m_iWritePos = 0;
    m_iReadPos = 0;

    for (int i=0; i<BUFFER_CAPACITY; i++)
        m_buffer[i] = 0;
}

//*************************************************************************************************
// Destructor
//*************************************************************************************************
CircularBuffer::~CircularBuffer()
{
}

//*************************************************************************************************
// Function append
/// @param s The number to add
//*************************************************************************************************
void CircularBuffer::append(short s)
{
    m_hMutex.lock();
    // Append the new value and increment the write marker position
    m_buffer[m_iWritePos++] = s;
    m_iWritePos = (m_iWritePos >= BUFFER_CAPACITY ? 0 : m_iWritePos);

    m_hMutex.unlock();
}

//*************************************************************************************************
// Function toArray
/// @param array A pointer to an already allocated array that will contain the values
/// @param size The size of the return array.
/// @param newOnly True to return only values that have been added since the last call of this function
/// @return The number of values read
//*************************************************************************************************
int CircularBuffer::toArray(short* array, int size, bool newOnly)
{
    // Cannot serialize more values than the buffer size
    size = min(size, BUFFER_CAPACITY);

    if (array == NULL)
    {
        cerr << "Error on void CircularBuffer::toArray : null pointer" << endl;
        return 0;
    }

    m_hMutex.lock();

    // Depending of the newOnly flag, serialize the <size> last values
    // or the values written since the last call of this method.
    if (!newOnly)
        m_iReadPos = (size < m_iWritePos ? m_iWritePos - size : BUFFER_CAPACITY - (size - m_iWritePos));

    int i;
    for (i=0; i<size && (!newOnly || m_iReadPos != m_iWritePos); i++)
    {
        m_iReadPos = (m_iReadPos >= BUFFER_CAPACITY ? 0 : m_iReadPos);
        array[i] = m_buffer[m_iReadPos++];
        //CBT printf("buffer%d\n",m_buffer[m_iReadPos]);
    }

    m_hMutex.unlock();

    return i;
}
